package org.budo.netty.servlet.server.connector.netty;

import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.budo.netty.servlet.server.handler.servlet.BudoServletRequest;
import org.budo.netty.servlet.server.handler.servlet.BudoServletResponse;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.cookie.ClientCookieEncoder;
import io.netty.handler.codec.http.cookie.Cookie;
import io.netty.handler.codec.http.cookie.DefaultCookie;

/**
 * @author lmw
 */
public class NettyUtil {
    public static String byteBufToString(ByteBuf byteBuf) {
        byte[] bytes = new byte[byteBuf.capacity()];
        byteBuf.readBytes(bytes);
        return new String(bytes);
    }

    public static void writeResponse(ChannelHandlerContext handlerContext, BudoServletRequest request, BudoServletResponse response) {
        HttpResponseStatus httpStatus = HttpResponseStatus.valueOf(response.getStatus());
        FullHttpResponse nettyResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, httpStatus);
        nettyResponse.setProtocolVersion(HttpVersion.HTTP_1_1);

        // write new session
        if (null != request && null != request.getSession(false) && request.getSession(false).isNew()) {
            Cookie nettyCookie = new DefaultCookie(BudoServletRequest.BUDO_SESSION_ID, request.getSession().getId());
            nettyCookie.setPath("/");
            String headerValue = ClientCookieEncoder.STRICT.encode(nettyCookie);

            nettyResponse.headers().add(HttpHeaderNames.SET_COOKIE, headerValue);
        }

        // write headers
        Set<Entry<String, String>> responseHeaders = response.getHeaders().entrySet();
        for (Map.Entry<String, String> responseHeader : responseHeaders) {
            nettyResponse.headers().add(responseHeader.getKey(), responseHeader.getValue());
        }

        // write response body
        byte[] responseBytes = response.getOutputStreamByteArray();
        if (responseBytes != null) {
            ByteBuf responseBuf = Unpooled.copiedBuffer(responseBytes);
            nettyResponse.content().writeBytes(responseBuf);

            response.setContentLength(responseBytes.length);
        }

        // flush
        handlerContext.writeAndFlush(nettyResponse);
        handlerContext.channel().close();
    }
}